package Filesystem
{
	import LessonPlans.AbstractLessonPlan;
	import LessonPlans.ILessonPlan;
	import LessonPlans.Tasks.Task;
	
	import flash.events.*;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.FileFilter;
	import flash.utils.ByteArray;

	public class LessonPlanFile extends EventDispatcher
	{
		private var file:File;
		private var stream:FileStream;
		
		public function LessonPlanFile(filePath:String=null)
		{
			if(filePath!=null&&filePath.search(".lp")!=filePath.length-3)
				filePath+=".lp";
			file = new File(filePath);
			stream = new FileStream();
		}
		
		public function browseForSave():void
		{
			file.addEventListener(Event.SELECT,browseForFileDispatch);
			file.browseForSave("Select destination to save LessonPlan file");
		}
		
		public function browseForOpen():void
		{
			file.addEventListener(Event.SELECT,browseForFileDispatch);
			file.browseForOpen("Select LessonPlan file for opening",new Array(new FileFilter("LessonPlan","*.lp","*.lp")));
		}
		
		private function browseForFileDispatch(e:Event):void
		{
			e.target.removeEventListener(Event.SELECT,browseForFileDispatch);
			if(file.extension!="lp")
				file = new File(file.url+".lp");
			dispatchEvent(e);
		}
		
		public function write(lessonPlan:ILessonPlan):void
		{
			var ba:ByteArray = getFormat(lessonPlan);
			stream.open(file,FileMode.WRITE);
			stream.writeBytes(ba,0,ba.length);
			stream.close();
		}

		public function read():ILessonPlan
		{
			var ba:ByteArray = new ByteArray();
			stream.open(file,FileMode.READ);
			while(stream.bytesAvailable)
				stream.readBytes(ba,ba.length,stream.bytesAvailable);
			stream.close();
			return getLessonPlan(ba);
		}
		
		private function getLessonPlan(ba:ByteArray):ILessonPlan
		{
			var byteValue:int;
			if(ba.bytesAvailable==0)
				return null;
			
			var title:String;
			var teacherName:String;
			var date:String;
			
			var taskName:String;
			var taskDescription:String;
			var taskResponse:String;
			var taskList:Vector.<Task> = new Vector.<Task>();
			
			var str:String = "";
			do
			{
				byteValue = ba.readUnsignedByte();
				if(byteValue!=0)
					str+=String.fromCharCode(byteValue);
				else
				{
					if(title==null)
						title = str;
					else if(teacherName==null)
						teacherName=str;
					else if(date==null)
						date=str;
					else if(taskName==null)
						taskName=str;
					else if(taskDescription==null)
						taskDescription=str;
					else if(taskResponse==null)
					{
						taskResponse=str;
						taskList.push(new Task(taskName,taskDescription,taskResponse));
						taskName=null;
						taskDescription=null;
						taskResponse=null;
					}
					str="";
				}
			}while(ba.bytesAvailable>0);
			
			var d:Date = new Date();
			d.time = parseInt(date);
			var lp:AbstractLessonPlan = new AbstractLessonPlan(title,teacherName,d);
			for each(var t:Task in taskList)
				lp.addTask(t);
			return lp;
		}
		
		/**
		 * Returns a ByteArray of the format: UTF/0UTF/0double/0 followed by array of UTF/0UTF/0UTF/0
		 * This translates to title/0teacherName/0date/0taskObject/0taskObject2/0... 
		 */
		private function getFormat(lessonPlan:ILessonPlan):ByteArray
		{
			if(lessonPlan==null)
				return null;
			var title:String = lessonPlan.title;
			var teacherName:String = lessonPlan.teacherName;
			var date:Number = lessonPlan.date.time;
			
			var ba:ByteArray = new ByteArray();
			ba.writeUTFBytes(title);
			ba.writeByte(0);
			ba.writeUTFBytes(teacherName);
			ba.writeByte(0);
			ba.writeUTFBytes(date.toString());
			ba.writeByte(0);
			
			for each(var t:Task in lessonPlan.taskList)
			{
				ba.writeUTFBytes(t.name);
				ba.writeByte(0);
				ba.writeUTFBytes(t.description);
				ba.writeByte(0);
				ba.writeUTFBytes(t.response);
				ba.writeByte(0);
			}
			return ba;
		}
	}
}